using RabbitMQ.Gateway.Config;
using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Threading.Tasks;
using System.Web.Configuration;

namespace RabbitMQ.Gateway.Admin
{
    /// <summary>
    /// queus manager 
    /// </summary>
    /// <author>cy.z</author>
	public class RabbitAdmin
	{
        private static readonly log4net.ILog log = RabbitMQ.Gateway.Log.loger;

        /// <summary>
        /// init and bind queue and exchange
        /// </summary>
        /// <param name="Connections"></param>
		internal static void InitializeExchanges(System.Collections.Generic.Dictionary<string, IConnection> Connections)
		{
            Configuration configuration;
            string _iswebsite = System.Configuration.ConfigurationManager.AppSettings["IsWebSite"] ?? string.Empty;
            if (_iswebsite.Equals("true", StringComparison.CurrentCultureIgnoreCase))
            {
                configuration = WebConfigurationManager.OpenWebConfiguration("~");
            }
            else
            {
                configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            }

           // Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
			AMQPObjectsDeclarationSection aMQPObjectsDeclarationSection = configuration.GetSection("AMQPAdmin/AMQPObjectsDeclaration") as AMQPObjectsDeclarationSection;
			if (aMQPObjectsDeclarationSection != null)
			{
				RabbitAdmin.CreateExchanges(Connections, aMQPObjectsDeclarationSection.ExchangeList);
				RabbitAdmin.CreateQueues(Connections, aMQPObjectsDeclarationSection.QueueList);
				RabbitAdmin.CreateBindings(Connections, aMQPObjectsDeclarationSection.BindingList);
			}
		}

        /// <summary>
        /// bind queue and exchange
        /// </summary>
        /// <param name="Connections"></param>
        /// <param name="list"></param>
		private static void CreateBindings(System.Collections.Generic.Dictionary<string, IConnection> Connections, BindingCollection list)
		{
            Parallel.For(0, list.Count, delegate (int i)
            {
                Binding binding = list[i];
                if (!Connections.ContainsKey(binding.Connection))
                {
                    log.WarnFormat("not found Connection {0} on create CreateBindings,The reason may be that create a connection failure", binding.Connection);
                }
                else
                {
                    using (IModel model = Connections[binding.Connection].CreateModel())
                    {
                        model.QueueBind(binding.Queue, binding.Exchange, binding.SuscriptionKey);
                    }
                }
            });
        }
        /// <summary>
        /// declare queue
        /// </summary>
        /// <param name="Connections"></param>
        /// <param name="list"></param>
		private static void CreateQueues(System.Collections.Generic.Dictionary<string, IConnection> Connections, QueueCollection list)
		{

			Parallel.For(0, list.Count, delegate(int i)
			{
				Queue queue = list[i];
                if (!Connections.ContainsKey(queue.Connection))
                {
                    log.WarnFormat("not found Connection {0} on create CreateQueues,The reason may be that create a connection failure", queue.Connection);
                }
                else
                {
                    using (IModel model = Connections[queue.Connection].CreateModel())
                    {
                        model.QueueDeclare(queue.Name, queue.Durable, queue.Exclusive, queue.AutoDelete, null);
                    }
                }
			});
		}
        /// <summary>
        /// declare exchange
        /// </summary>
        /// <param name="Connections"></param>
        /// <param name="list"></param>
		private static void CreateExchanges(System.Collections.Generic.Dictionary<string, IConnection> Connections, ExchangeCollection list)
		{
			Parallel.For(0, list.Count, delegate(int i)
			{
				Exchange exchange = list[i];
                if (!Connections.ContainsKey(exchange.Connection))
                {
                    log.WarnFormat("not found Connection {0} on create exchange,The reason may be that create a connection failure",exchange.Connection);
                }
                else
                {
                    using (IModel model = Connections[exchange.Connection].CreateModel())
                    {
                        model.ExchangeDeclare(exchange.Name, exchange.Type.ToString(), exchange.Durable, exchange.AutoDelete, null);
                    }
                }
			});
		}
	}
}
